package rpt.yto.flex.remote.data.biz;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import rpt.yto.flex.remote.data.bean.RPTTableBBean;
import rpt.yto.flex.remote.data.bean.StatisticB2Bean;
import rpt.yto.flex.remote.data.bean.StatisticB3Bean;
import rpt.yto.flex.remote.data.bean.StatisticB4Bean;
import rpt.yto.flex.remote.data.bean.StatisticB5Bean;
import rpt.yto.flex.remote.data.bean.StatisticBBean;
import rpt.yto.flex.remote.data.bean.StatisticHBean;
import rpt.yto.flex.remote.data.dao.ITableDAO;
import rpt.yto.util.beans.SuperBean;

@SuppressWarnings({ "unchecked", "unused" , "static-access" })
public class TableBiz {

	private List<Map<String , Object>> results;
	
	private static ApplicationContext context;
	private static ITableDAO tableDAO;

	private final String SUCCESS = "true";
	
	private static Map<String , Integer> billtype = null;
	
	static {
		context = new ClassPathXmlApplicationContext("applicationContext.xml");
		tableDAO = (ITableDAO) context.getBean("tableDAO");
		
		initBillTypeMap();
		
	}
	
	private static final void initBillTypeMap() {
		
		billtype = new ConcurrentHashMap<String , Integer>();
		billtype.put("allpsn", 1);
		billtype.put("allpsn.dept", 2);
		billtype.put("allpsn.mng", 3);
		billtype.put("allpsn.province", 4);
		billtype.put("headpsn", 5);
		billtype.put("deptpsn", 6);
		billtype.put("dirpsn.province", 7);
		billtype.put("dirpsn.center", 8);
		billtype.put("dirpsn.corp", 9);
		billtype.put("joinpsn.center", 10);
		billtype.put("joinpsn.corp", 11);
		billtype.put("dirpsn" , 12);
		billtype.put("rpt.totalpsn", 13);
		billtype.put("rpt.psnchange", 14);
		billtype.put("rpt.allpsnchange", 15);
		
	}
	
	public String resultTableJSON(String reportcode , String pos) throws Exception { 
		
		Map<String , Object> param = new ConcurrentHashMap<String , Object>();
		param.put("reportcode", reportcode);
		param.put("pos", pos);
		
		List<RPTTableBBean> tableList = tableDAO.queryTableByCode(param);
		
		if(tableList != null && tableList.size() > 0) {
			results = new ArrayList<Map<String , Object>>();
			
			for(RPTTableBBean table : tableList) {
				results.add(table.getBeanToMap());
			}
			
			return JSONArray.fromObject(results).toString();
			
		}
		
 		return null;
	}
	
	public String saveQueryData(String billtype , String period , String data) throws Exception {
		
		Object genKey = null;
		try {
			StatisticHBean hBean = new StatisticHBean();
			hBean.setBilltype(billtype);
			hBean.setPeriod(period);
			
			genKey = tableDAO.insertHeadData(hBean);
			
			Object[] objArray = JSONArray.fromObject(data).toArray();
			
			switch(this.billtype.get(billtype)) {
				
				case 1 :
					return tableDAO.insertBodyData(jsonToBean(new ArrayList<SuperBean>(), objArray, genKey, StatisticBBean.class) , "insertBodyDataByB");
				case 2 : 
				case 3 : 
				case 4 : 
				case 5 : 
				case 6 : 
				case 7 : 
				case 8 : 
				case 9 : 
				case 10 : 
				case 11 : 
					return tableDAO.insertBodyData(jsonToBean(new ArrayList<SuperBean>(), objArray, genKey, StatisticB2Bean.class) , "insertBodyDataByB2");
					
				case 12 : 
					return tableDAO.insertBodyData(jsonToBean(new ArrayList<SuperBean>(), objArray, genKey, StatisticB3Bean.class) , "insertBodyDataByB3");
					
				case 13 :
					return tableDAO.insertBodyData(jsonToBean(new ArrayList<SuperBean>(), objArray, genKey, StatisticB4Bean.class) , "insertBodyDataByB4");
					
				case 14 :
				case 15 :
					return tableDAO.insertBodyData(jsonToBean(new ArrayList<SuperBean>(), objArray, genKey, StatisticB5Bean.class) , "insertBodyDataByB5");
					
				default :
					
					return "true";
			
			}
			
			
			
		} catch(Exception e) {
			if(genKey != null)
				deleteStatisticData(String.valueOf(genKey));
			
			return "false";
		}
		
	}
	
	private final List<SuperBean> jsonToBean(List<SuperBean> beanList , Object[] objArray , Object genKey , Class beanType) throws Exception {
		
		for(Object jsonObj : objArray) {
			SuperBean bean = (SuperBean) Class.forName(beanType.getName()).newInstance();
			String[] keys = bean.getAttributeNames();
			
			for(String key : keys) {
				bean.setAttributeValue(key, ((JSONObject)jsonObj).get(key));
			}
			
			bean.setAttributeValue("pk_statistic", String.valueOf(genKey));
			beanList.add(bean);
		}
		
		return beanList;
		
	}
	
	public String queryHeadData(String billtype , String period) throws Exception {
		
		Map<String , Object> paramMap = new ConcurrentHashMap<String , Object>();
		paramMap.put("billtype", billtype);
		paramMap.put("period", period == null ? "" : period);
		paramMap.put("tablename", "rpt_statistic_h");
		
		return JSONArray.fromObject(tableDAO.queryBeanByCondition(paramMap, StatisticHBean.class)).toString();
		
	}
	
	public String queryBodyData(String pk_statistic , String billtype) throws Exception {
		
		Map<String , Object> paramMap = new ConcurrentHashMap<String , Object>();
		paramMap.put("pk_statistic", pk_statistic);
		paramMap.put("rowno", "rowno");
		Class beanType = null;
		switch (this.billtype.get(billtype)) {
		case 1:
			paramMap.put("tablename", "rpt_statistic_b");
			beanType = StatisticBBean.class;
			break;

		case 2 :
		case 3 :
		case 4 :
		case 5 :
		case 6 :
		case 7 :
		case 8 :
		case 9 :
		case 10 :
		case 11 :
			beanType = StatisticB2Bean.class;
			paramMap.put("tablename", "rpt_statistic_b2");
			break;
			
		case 12 :
			beanType = StatisticB3Bean.class;
			paramMap.put("tablename", "rpt_statistic_b3");
			break;
			
		case 13 : 
			beanType = StatisticB4Bean.class;
			paramMap.put("tablename", "rpt_statistic_b4");
			break;
			
		case 14 : 
		case 15 :
			beanType = StatisticB5Bean.class;
			paramMap.put("tablename", "rpt_statistic_b5");
			break;
			
		default:
			break;
		}
		
		
		return JSONArray.fromObject(tableDAO.queryBeanByCondition(paramMap, beanType)).toString();
		
	}
	
	public String deleteStatisticData(String pk_statistic) throws Exception {
		
		Map<String , Object> paramMap = new ConcurrentHashMap<String , Object>();
		paramMap.put("pk_statistic", pk_statistic);
		
		paramMap.put("tablename", "rpt_statistic_b");
		tableDAO.deleteStatisticData(paramMap);
		
		paramMap.put("tablename", "rpt_statistic_b2");
		tableDAO.deleteStatisticData(paramMap);
		
		paramMap.put("tablename", "rpt_statistic_b3");
		tableDAO.deleteStatisticData(paramMap);
		
		paramMap.put("tablename", "rpt_statistic_b4");
		tableDAO.deleteStatisticData(paramMap);
		
		paramMap.put("tablename", "rpt_statistic_b5");
		tableDAO.deleteStatisticData(paramMap);
		
		paramMap.put("tablename", "rpt_statistic_h");
		
		return tableDAO.deleteStatisticData(paramMap);
		
	}
	
	public String insertHeadTable(String reportcode , String reportname) throws Exception {
		
		Map<String , String> param = new ConcurrentHashMap<String , String>();
		param.put("reportcode", reportcode);
		param.put("reportname", reportname);
		
		String pk_table = tableDAO.queryExsits(reportcode);
		if(pk_table != null) 
			return pk_table;
		
		return tableDAO.insertHeadTable(param);
		
	}
	
	public String insertBodyTable(String json) throws Exception {
		
		List<Map<String , String>> jsonList = (List<Map<String, String>>) JSONArray.toCollection(JSONArray.fromObject(json), Map.class);
		String pk_table = null;
		
		for(Map param : jsonList) {
			pk_table = (String) param.get("pk_table");
			tableDAO.insertBodyTable(param);
		}
		
		return JSONArray.fromObject(tableDAO.queryTableBByPK(pk_table)).toString();
	}
	
	public String deleteBodyTableByPK(String pk_table) throws Exception {
		tableDAO.deleteBodyTable(pk_table);
		return pk_table;
	}

}
